package eu.briano.suirvellancecamera;





import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.session.AccessTokenPair;
import eu.briano.suirvellancecamera.service.Background;
import eu.briano.suirvellancecamera.service.Background.LocalBinder;

import android.app.*;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.IBinder;

import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.widget.ImageView;



public class SuirvellanceCameraActivity extends Activity {
	Camera c = null;
	Acquire a =null;
	ImageProcessing ip = null;

	
	
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle item selection
		switch (item.getItemId()) {
		/*
		case R.id.start:
			a.start(null) ;
			return true;
		case R.id.stop:
			a.stop(null);
			return true;
		 */
		case R.id.quit:
			a.stop(null);
			this.finish();
			return true;

		case R.id.dropbox:
			try {
				mDBApi.getSession().startAuthentication(SuirvellanceCameraActivity.this);
			} catch (Exception e) {
				Log.e(Utils.logName,"DropBox error on init:",e);
			}				
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.i(Utils.logName,"onCreate");

		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.main);

		a = new AcquireVideo(c);
		
		
		
		ip = new ImageProcessing();
		a.setOnImageReady(new OnImageReady() {
			@Override
			public void callBack(int w,int h,byte [] object,long timeStart) {
				process(w,h,object,timeStart);
			}
		});
		
		mDBApi = Utils.dropBoxConnect(this);	

	}

	// only after on stop
	@Override
	protected void onRestart() {
		super.onPause();
		Log.i(Utils.logName,"onRestart");
	}	

	@Override
	protected void onStart() {
		super.onPause();
		Log.i(Utils.logName,"onStart");
		Intent intent = new Intent(this, Background.class);
		bindService(intent, mConnection, Context.BIND_AUTO_CREATE);		
	}
	@Override
	protected void onResume() {
		super.onResume();
		Log.i(Utils.logName,"onResume");
		dropBoxPostResume();
		c = Camera.open();
		
		a.setCamera(c);

		SurfaceView surfaceView = (SurfaceView)findViewById(R.id.preview);
		SurfaceHolder holder = surfaceView.getHolder();
		holder.addCallback((AcquireVideo)a);
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		a.start(null);
	}

	@Override
	protected void onPause() {
		super.onPause();

		try {
			if (c != null)
				a.stop(null);
			c.release();
		} catch (Exception e) {

		}
		Log.i(Utils.logName,"onPause");
	}
	@Override
	protected void onStop() {
		super.onStop();
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }		
		Log.i(Utils.logName,"onStop");
	}

	@Override
	protected void onDestroy() {
		super.onStop();

		Log.i(Utils.logName,"onDestroy");
	}





	@Override
	public void finish() {
		// TODO Auto-generated method stub
		super.finish();
		Log.i(Utils.logName,"finish");
	}


	Bitmap display = Bitmap.createBitmap(Utils.ipSize, Utils.ipSize,Bitmap.Config.ARGB_8888);


	synchronized private void process(int bW, int bH,byte[] buffer,long start) {

		try {
		
			Log.v(Utils.logName, "\t\tprocess start");
			int w = Utils.ipSize;
			int h = w;
				
			boolean doPocessing = true;
			if (buffer != null) {

				int [][][] image = new int [Utils.ipSize][Utils.ipSize][3];
				float [][][] yuvImage = new float [Utils.ipSize][Utils.ipSize][3];

				ip.resizeYUV(bW,bH,buffer,image);
				//convert to float
				ip.writeBitMapYUVToArrayF(image, yuvImage);



				if (doPocessing) {
					ip.calculateBckYUV(w, h, yuvImage);
					Log.v(Utils.logName, "calculateBckYUV at "+(Utils.now()-start));
					//binary on green
					ip.diffBackGroundYUV(w, h, yuvImage,image);
					Log.v(Utils.logName, "diffBackGroundYUV at "+(Utils.now()-start));


					ip.calculateNoiseMoving(w, h, image);
					Log.v(Utils.logName, "calculateNoiseMoving at "+(Utils.now()-start));
					ip.snoozeNoiseZone(w, h, image);
					Log.v(Utils.logName, "snoozeNoiseZone at "+(Utils.now()-start));
					ip.removeSparkle(w, h, image);			
					Log.v(Utils.logName, "removeSparkle at "+(Utils.now()-start));

					float change = ip.pow(image);
					Log.v(Utils.logName, "change at "+(Utils.now()-start));
					Log.v(Utils.logName, "changed is "+change);
					Log.v(Utils.logName, "estimation done at "+(Utils.now()-start));


					ip.writeArrayToBitMap(image,display);


					if (change > Utils.maxChange) {
						String debugText = "Change:"+change+"/"+Utils.maxChange;
						
						new AlarmNotifier(this).sendAlarm(buffer, Utils.previewFormat, bW, bH,display,debugText);
					}
				} else
					ip.writeArrayToBitMap(image,display);

				runOnUiThread(new Runnable() {
					public void run() {
						try {
							ImageView iv = (ImageView) findViewById(R.id.processed);
							iv.setImageBitmap(display);
							iv.setAlpha(128);
							iv.invalidate();
						} catch (Exception e) {
							Log.e(Utils.logName, "error setting bitmap"+e.toString());
						}

					}
				});		
				Log.v(Utils.logName, "process done in"+(Utils.now()-start));
			}

		} catch (Exception e) {
			Log.e(Utils.logName,"process error ",e);
		}
		Log.v(Utils.logName,"processed in "+(Utils.now()-start));
	}

	private DropboxAPI<AndroidAuthSession> mDBApi;	
	
	private void dropBoxPostResume() {
		if (mDBApi != null && mDBApi.getSession() != null &&
				mDBApi.getSession().authenticationSuccessful()) {
			try {
				mDBApi.getSession().finishAuthentication();
				AccessTokenPair tokens = mDBApi.getSession().getAccessTokenPair();
				SharedPreferences sp =  getSharedPreferences(Utils.yascPreferencesName,MODE_PRIVATE);
				Editor e = sp.edit();
				e.putString(Utils.dropBoxTokenKey   , tokens.key);
				e.putString(Utils.dropBoxTokenSecret, tokens.secret);
				e.commit();
				
				if (mBound)
					mService.reloadDropBoxConf();
				
				
				Log.i(Utils.logName,"DropBox  authenticating ok");
			} catch (IllegalStateException e) {
				Log.i(Utils.logName,"DropBox error authenticating", e);
			}
		}
	}
	
	@Override
	protected void finalize() throws Throwable {
		// TODO Auto-generated method stub
		super.finalize();
		if (c != null)
			c.stopPreview();
		Log.v(Utils.logName," finalize !");

	}

	Background mService;
	boolean mBound = false;
	private ServiceConnection mConnection = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName className,
				IBinder service) {
			// We've bound to LocalService, cast the IBinder and get LocalService instance
			LocalBinder binder = (LocalBinder) service;
			mService = binder.getService();
			mBound = true;
		}

		@Override
		public void onServiceDisconnected(ComponentName arg0) {
			mBound = false;
		}
	};	





}